home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun3.md / machAsm.s < prev    next >
Text File  |  1992-12-18  |  13KB  |  499 lines

  1. |* machAsm.s --
  2. |*
  3. |*     Contains misc. assembler routines for the SUN.
  4. |*
  5. |* Copyright (C) 1985 Regents of the University of California
  6. |* All rights reserved.
  7. |*
  8. |* rcs = $Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun3.md/machAsm.s,v 9.1 91/03/29 17:53:38 shirriff Exp $ SPRITE (Berkeley)
  9. |*
  10.  
  11. #include "machConst.h"
  12. #include "machAsmDefs.h"
  13.  
  14. |*----------------------------------------------------------------------------
  15. |*
  16. |* MachRunUserProc -
  17. |*
  18. |*    void    MachRunUserProc()
  19. |*
  20. |* Results:
  21. |*         Restore registers and return to user space.  Our caller has set
  22. |*    up our exception stack for us.
  23. |*
  24. |* Side effects:
  25. |*    Registers restored.
  26. |*
  27. |*----------------------------------------------------------------------------
  28.  
  29.     .text
  30.     .globl    _MachRunUserProc
  31. _MachRunUserProc:
  32.     RestoreUserFpuState()
  33.     RestoreUserRegs()
  34.     rte                            | Return to user space
  35.  
  36. |*---------------------------------------------------------------------
  37. |*
  38. |* Mach_GetEtherAddress -
  39. |*
  40. |*    Copies the ethernet address from the id prom into the
  41. |*    argument structure.  The prom is mapped funny, so the
  42. |*    loop increments the pointer into the prom as specified in
  43. |*    the sun-2 architecture manual, section 4.8
  44. |*
  45. |*    Mach_GetEtherAddress(etherAddressPtr)
  46. |*        EtherAddress *etherAddressPtr;    destination of copy
  47. |*
  48. |* Results:
  49. |*     The argument struct has the prom's ethernet address.
  50. |*
  51. |* Side effects:
  52. |*    None.
  53. |*
  54. |*---------------------------------------------------------------------
  55.  
  56.     .text
  57.     .globl    _Mach_GetEtherAddress
  58. _Mach_GetEtherAddress:
  59.     movl    sp@(4),a0        | Get pointer to target ethernet address
  60.     movl    #(6 - 1),d0        | loop counter
  61.     movl    #VMMACH_ETHER_ADDR,a1    | The Prom address of the ethernet addr
  62. etherloop:
  63.     movsb    a1@,d1            | Copy one byte of the ethernet address
  64.     movb    d1,a0@            |   from prom to the target address.
  65.     addql    #1,a0            | bump target pointer
  66.     addl    #VMMACH_IDPROM_INC,a1    | bump prom address, as per sec 4.8
  67.     dbra        d0, etherloop        | loop 6 times
  68.     rts                    | Return
  69.  
  70. |*---------------------------------------------------------------------
  71. |*
  72. |* Mach_ContextSwitch -
  73. |*
  74. |*    Mach_ContextSwitch(fromProcPtr, toProcPtr)
  75. |*
  76. |*    Switch the thread of execution to a new processes.  This routine
  77. |*    is passed a pointer to the process to switch from and a pointer to
  78. |*    the process to switch to.  It goes through the following steps:
  79. |*
  80. |*    1) Change to the new context.
  81. |*    2) Push the status register and the
  82. |*       user stack pointer onto the stack.
  83. |*    3) Push the source and destination function codes onto the stack.
  84. |*    4) Push a magic number onto the stack to see if it gets trashed.
  85. |*    5) Save all of the registers d0-d7, a0-a7 for the process being
  86. |*       switched from.
  87. |*    6) Restore general registers and the status register of the process 
  88. |*       being switched to.
  89. |*    7) Verify the magic number.
  90. |*    8) Return in the new process.
  91. |*    
  92. |*    The kernel stack is changed implicitly when the registers are restored.
  93. |*
  94. |* Results:
  95. |*     None.
  96. |*
  97. |* Side effects:
  98. |*    The kernel stack, all general purpose registers and the status register
  99. |*    are all changed.
  100. |*
  101. |*---------------------------------------------------------------------
  102.  
  103.     .globl _Mach_ContextSwitch
  104. _Mach_ContextSwitch:
  105. |*
  106. |* Setup up the hardware context register for the destination process.
  107. |* VmMach_SetupContext(toProcPtr) returns the context register value.
  108. |*
  109.     movl    sp@(8), sp@-
  110.     jsr        _VmMach_SetupContext
  111.     addql    #4, sp
  112. #ifdef sun3
  113.     movsb    d0, VMMACH_CONTEXT_OFF
  114. #else 
  115.     movsb    d0,VMMACH_USER_CONTEXT_OFF:w 
  116.     movsb    d0,VMMACH_KERN_CONTEXT_OFF:w
  117. #endif
  118.     movl    sp, a1            | Save the stack pointer value in a1
  119.     movw    sr, sp@-        | Save the current value of the status
  120.                     |     register on the stack.
  121.     movw    #MACH_SR_HIGHPRIO, sr    | Lock out interrupts.
  122.     movl    usp, a0          | Push the user stack pointer onto 
  123.     movl    a0, sp@-        |     the stack.
  124.     movl    #MAGIC, sp@-        | Put the magic number on the stack.
  125.  
  126.     movl    a1@(4), a0        | d0 = fromProcPtr
  127.     addl    _machStatePtrOffset, a0    | a0 = pointer to mach struct
  128.     movl    a0@, a0
  129.  
  130. #if 0
  131.                                         | Save the floating point state.
  132.     tstl        _mach68881Present
  133.     beq         1f
  134.     fsave       a0@(MACH_SWITCH_FP_STATE_OFFSET)
  135.     tstb        a0@(MACH_SWITCH_FP_STATE_OFFSET)
  136.     beq         1f
  137.     fmovem      #0xff, a0@(MACH_SWITCH_FP_REGS_OFFSET)
  138.     fmovem      fpc/fps/fpi, a0@(MACH_SWITCH_FP_CTRL_REGS_OFFSET)
  139.     frestore    _mach68881NullState
  140. 1:
  141. #endif
  142.                     | Save registers for process being
  143.                     |     switched from
  144.     moveml    #0xffff, a0@(MACH_SWITCH_REGS_OFFSET)
  145.  
  146.     movl    a1@(8), a0        | a0 = toProcPtr
  147.     addl    _machStatePtrOffset, a0 | a0 = pointer to mach struct
  148.     movl    a0@, a0
  149.  
  150. #if 0
  151.                                         | Restore the floating point state.
  152.         tstl        _mach68881Present
  153.     beq         2f
  154.     tstb        a0@(MACH_SWITCH_FP_STATE_OFFSET)
  155.     beq         1f
  156.     fmovem      a0@(MACH_SWITCH_FP_REGS_OFFSET), #0xff
  157.     fmovem      a0@(MACH_SWITCH_FP_CTRL_REGS_OFFSET), fpc/fps/fpi
  158. 1:
  159.     frestore    a0@(MACH_SWITCH_FP_STATE_OFFSET)
  160. 2:
  161. #endif
  162.                     | Restore registers for process being
  163.                     |     switched to
  164.     moveml    a0@(MACH_SWITCH_REGS_OFFSET), #0xffff
  165.  
  166.     movl    #MAGIC, d0        | Check against the magic number
  167.     cmpl    sp@, d0            |
  168.     beq        3f            |
  169.     trap    #15            |
  170.  
  171. 3:
  172.     addql    #4, sp            | Pop the magic number.
  173.     movl    sp@+, a0        | Restore the user stack pointer.
  174.     movl    a0, usp
  175.     movw    sp@+, sr        | Restore the status register.
  176.  
  177. |*
  178. |* Get a pointer to the current machine state struct.
  179. |*
  180.     .globl    _proc_RunningProcesses, _machCurStatePtr, _machStatePtrOffset
  181.     movl    _proc_RunningProcesses, a0
  182.     movl    a0@, a0
  183.     addl    _machStatePtrOffset, a0
  184.     movl    a0@, a0
  185.     movl    a0, _machCurStatePtr
  186. |*
  187. |* Set the end of the kernel stack marker for kdbx.
  188. |*
  189.     .globl    _dbgMaxStackAddr
  190.     movl    a0@(MACH_KERN_STACK_START_OFFSET), d0
  191.     addl    #MACH_KERN_STACK_SIZE, d0
  192.     movl    d0, _dbgMaxStackAddr
  193.  
  194.     rts
  195.  
  196. |*---------------------------------------------------------------------
  197. |*
  198. |* Mach_TestAndSet --
  199. |*
  200. |*    int Mach_TestAndSet(intPtr)
  201. |*        int *intPtr;
  202. |*
  203. |*         Test and set an operand.
  204. |*
  205. |* Results:
  206. |*         Returns 0 if *intPtr was zero and 1 if *intPtr was non-zero.  Also
  207. |*    in all cases *intPtr is set to a non-zero value.
  208. |*
  209. |* Side effects:
  210. |*     None.
  211. |*
  212. |*---------------------------------------------------------------------
  213.  
  214.     .globl _Mach_TestAndSet
  215. _Mach_TestAndSet:
  216.     clrl    d0        | Set the return register to 0.
  217.     movl    sp@(4), a0    | Move the address of the operand to a0.
  218.     tas        a0@        | Test and set the operand.
  219.     beq        1f        | If it wasn't set then just return 0.
  220.     moveq    #1, d0        | Otherwise return 1.
  221. 1:
  222.     rts
  223.  
  224. |*---------------------------------------------------------------------
  225. |*
  226. |* Mach_GetMachineType -
  227. |*
  228. |*    Returns the type of machine that is stored in the id prom.
  229. |*
  230. |*    int    Mach_GetMachineType()
  231. |*
  232. |* Results:
  233. |*     The type of machine (1 or 2).
  234. |*
  235. |* Side effects:
  236. |*    None.
  237. |*
  238. |*---------------------------------------------------------------------
  239.  
  240.     .text
  241.     .globl    _Mach_GetMachineType
  242. _Mach_GetMachineType:
  243.     clrl    d0                    | Clear the return register
  244.     movl    #VMMACH_MACH_TYPE_ADDR, a0  | Get the address of the machine type
  245.                     |     in a register.
  246.     movsb   a0@,d0            | Store the machine type in the return
  247.                     |     register.
  248.     rts
  249.  
  250.  
  251. |*
  252. |* ----------------------------------------------------------------------
  253. |*
  254. |* MachMonNmiNop --
  255. |*
  256. |*       The code which is executed when we redirect non-maskable
  257. |*       interrupts on the Sun-2.  When the AMD chip timer #1 interrupts,
  258. |*       it causes a level 7 interrupt which is nonmaskable. The timer
  259. |*       output has to be cleared to clear the interrupt condition. The
  260. |*       timer is setup to repeatedly interrupt every 25ms.
  261. |*
  262. |*    NOTE: This is code taken from locore.s.
  263. |*
  264. |* Results:
  265. |*    None.
  266. |*
  267. |* Side effects:
  268. |*    The AMD chip's timer #1 output is cleared.
  269. |*
  270. |* ----------------------------------------------------------------------
  271. |*
  272.  
  273. #define    AMD9513_CSR    0xee0002
  274.  
  275.     .globl _MachMonNmiNop
  276. _MachMonNmiNop:
  277. #ifdef sun2
  278.         moveml  #0xC0C0,sp@-            | Save d0,d1,a0,a1
  279.         movw    #0xFFE1, AMD9513_CSR    | Clear the output of timer #1 
  280.                     | on the AMD timer chip to clear
  281.                     | the current interrupt.
  282. | Move the upper half of the status register to the leds.
  283. |
  284.         movb    sp@(16),d0        | Move the upper half of the sr to d0
  285.         eorb    #0xFF,d0        | Exclusive or the bits.
  286.         movsb   d0,0xB                  | Move it to the leds.
  287.     moveml  sp@+,#0x0303            | restore regs
  288. #endif /* sun2 */
  289.         rte
  290.  
  291.  
  292. |*
  293. |* ----------------------------------------------------------------------
  294. |*
  295. |* Mach_MonTrap --
  296. |*
  297. |*    Trap to the monitor.  This involves dummying up a trap stack for the
  298. |*    monitor, allowing non-maskable interrupts and then jumping to the
  299. |*    monitor trap routine.  When it returns, non-maskable interrupts are
  300. |*    enabled and we return.
  301. |*
  302. |* Results:
  303. |*    None.
  304. |*
  305. |* Side effects:
  306. |*    None.
  307. |*
  308. |* ----------------------------------------------------------------------
  309. |*
  310.  
  311.     .globl    _Mach_MonTrap
  312. _Mach_MonTrap:
  313.     jsr    _Mach_MonStartNmi    | Restart non-maskable interrupts.
  314.     movl    sp@(4), a0        | Address to trap to.
  315.     clrw    sp@-            | Put on a dummy vector offset register.
  316.     movl    #1f, sp@-        | Put the return address onto the stack.
  317.     movw    sr, sp@-        | Push the current status register.
  318.     jra    a0@            | Trap
  319. 1:    jsr    _Mach_MonStopNmi    | Stop non-maskable interrupts.
  320.     rts
  321.  
  322. |*
  323. |* ----------------------------------------------------------------------
  324. |*
  325. |* MachSetVBR --
  326. |*
  327. |*    Set the value of the vector base register to that value that is 
  328. |*    passed in on the stack.
  329. |*
  330. |*    MachSetVBR(vectorBaseAddr)
  331. |*        Address    vectorBaseAddr;
  332. |*    
  333. |* Results:
  334. |*    None.
  335. |*
  336. |* Side effects:
  337. |*    Vector base register is changed.
  338. |*
  339. |* ----------------------------------------------------------------------
  340. |*
  341.  
  342.     .globl    _MachSetVBR
  343. _MachSetVBR:
  344.     movl    sp@(4),d0        | Get vector base address.
  345.     movc    d0, vbr            | Load vector base register.
  346.     rts    
  347.  
  348. |*
  349. |* ----------------------------------------------------------------------
  350. |*
  351. |* MachGetVBR --
  352. |*
  353. |*    Get the value of the vector base register.
  354. |*
  355. |*    int    MachGetVBR()
  356. |*    
  357. |* Results:
  358. |*    The value of the vector base register.
  359. |*
  360. |* Side effects:
  361. |*    None.
  362. |*
  363. |* ----------------------------------------------------------------------
  364. |*
  365.  
  366.     .globl    _MachGetVBR
  367. _MachGetVBR:
  368.     movc    vbr, d0            | Get vector base register.
  369.     rts
  370.  
  371. |*
  372. |* ----------------------------------------------------------------------
  373. |*
  374. |* Mach_GetStackPointer --
  375. |*
  376. |*    Return the value of the user's stack pointer.
  377. |*
  378. |* Results:
  379. |*    Returns the user stack pointer value.
  380. |*
  381. |* Side effects:
  382. |*    None.
  383. |*
  384. |* ----------------------------------------------------------------------
  385. |*
  386.     .globl _Mach_GetStackPointer
  387. _Mach_GetStackPointer:
  388.     movc usp, d0
  389.     rts
  390. /*
  391.  * Routines between MachProbeStart() and MachProbeEnd() will return
  392.  * FAILURE if a bus error occurs in them.
  393.  */
  394.     .even
  395.     .globl _MachProbeStart
  396. _MachProbeStart:
  397.  
  398. /*
  399.  *----------------------------------------------------------------------
  400.  *
  401.  * Mach_Probe --
  402.  *
  403.  *    Copy a block of memory from one virtual address to another handling
  404.  *    bus errors that may occur. This    routine is intended to be used to 
  405.  *    probe for memory mapped devices.
  406.  *
  407.  * NOTE: This trap handlers force this routine to return SYS_NO_ACCESS if an
  408.  *     bus error occurs.
  409.  *
  410.  * Calling sequences:
  411.  *
  412.  * ReturnStatus
  413.  * Mach_Probe(size, srcAddress, destAddress)
  414.  *    int        size;     Size in bytes of the read to do. Must
  415.  *                  1, 2, 4, or 8  
  416.  *  Address    srcAddress;     Address to read from. 
  417.  *  Address    destAddress;     Address to store the read value. 
  418.  *    
  419.  *
  420.  * Results:
  421.  *    SUCCESS if the copy worked and  SYS_NO_ACCESS otherwise
  422.  *
  423.  * Side effects:
  424.  *    None.
  425.  *----------------------------------------------------------------------
  426.  */
  427.     .globl _Mach_Probe
  428. _Mach_Probe:
  429.     /*
  430.      * Move arguments into registers d0 gets size, a1 gets src address
  431.      * and a0 gets destAddress.
  432.      */
  433.     movel sp@(12),a0
  434.     movel sp@(8), a1
  435.     movel sp@(4),d0
  436.     /*
  437.      * Index based on the size argument to the correct moveb, movew, 
  438.      * movel or (simulated moved) instruction. Values other than 1,2,4, or
  439.      * 8 
  440.      */
  441.     subql #1,d0
  442.     moveq #7,d1
  443.     cmpl d1,d0
  444.     jhi bad
  445.     asll #1,d0
  446. 1:
  447.     movew pc@(2f-1b-2:b,d0:l),d1
  448.     clrl d0
  449.     jmp pc@(2,d1:w)
  450. 2:
  451.     .word oneByte-2b
  452.     .word twoByte-2b
  453.     .word bad-2b
  454.     .word fourByte-2b
  455.     .word bad-2b
  456.     .word bad-2b
  457.     .word bad-2b
  458.     .word eightByte-2b
  459. oneByte:
  460.     moveb a1@,a0@
  461.     rts
  462. twoByte:
  463.     movew a1@,a0@
  464.     rts
  465. fourByte:
  466.     movel a1@,a0@
  467.     rts
  468. eightByte:
  469.     movel a1@,a0@
  470.     movel a1@(4),a0@(4)
  471.     rts
  472. bad:
  473.     moveq #1,d0
  474.     rts
  475.     .globl _MachProbeEnd
  476.     .even
  477. _MachProbeEnd:
  478. |*----------------------------------------------------------------------------
  479. |*
  480. |* Mach_Return2 -
  481. |*
  482. |*    void    MachReturn2(int val)
  483. |*
  484. |* Results:
  485. |*         Sets the second return value to val.  This is used for Unix
  486. |*    compatibility for system calls that return two values.
  487. |*
  488. |* Side effects:
  489. |*    d1 <- val
  490. |*
  491. |*----------------------------------------------------------------------------
  492.  
  493.     .text
  494.     .globl    _Mach_Return2
  495. _Mach_Return2:
  496.     movl    sp@(4),d1
  497.     rts
  498.